﻿using FastMvc.Crud;
using FastMvc.Exceptions;
using FastMvc.Repositories;
using JQ.SAAS.DTO.OrgRole;
using JQ.SAAS.Entity;
using JQ.SAAS.IService;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace JQ.SAAS.Service
{
    public class OrgRoleService : CrudService<org_role, OrgRoleDto, string, OrgRoleListRequestDto, OrgRoleCreateUpdateDto, OrgRoleCreateUpdateDto>, IOrgRoleService
    {
        private IRepository<org_menu_set> _menuSetRepository;
        private IRepository<org_role_menu> _roleMenuRepository;

        public OrgRoleService(
            IRepository<org_role> repository,
            IRepository<org_role_menu> roleMenuRepository,
            IRepository<org_menu_set> menuSetRepository)
            : base(repository)
        {
            _roleMenuRepository = roleMenuRepository;
        }

        public async Task<List<OrgRoleMenuSetDto>> GetRoleMenus(string sId)
        {
            var datas = await _roleMenuRepository.GetAllAsync(t => t.sRoleId == sId);

            return datas.Select(t => MapTo<OrgRoleMenuSetDto, org_role_menu>(t)).ToList();
        }

        public async Task SetRoleMenus(string sId, List<OrgRoleMenuSetDto> Menus)
        {
            var mIds = Menus.Select(t => t.sMenuId).ToList();
            var allMenus = await _menuSetRepository.GetAllAsync(t => mIds.Contains(t.sId));

            var errSet = allMenus.FirstOrDefault(t => !string.IsNullOrEmpty(t.sParentMenuId) && !mIds.Contains(t.sParentMenuId));
            if (errSet != null)
            {
                throw new ApiException($"配置格式错误：菜单{errSet.sShowName} 的上级菜单未选中！");
            }

            // 获取当前已经配置的
            var oldMenus = await _roleMenuRepository.GetAllAsync(t => t.sRoleId == sId);
            var oldmIds = oldMenus.Select(t => t.slMenuId).ToList();
            // 待删除的
            var delIds = oldMenus.Where(t => !mIds.Contains(t.slMenuId)).Select(t => t.sId).ToList();
            // 待新增的
            var adMenus = allMenus.Where(t => !oldmIds.Contains(t.sMenuId)).ToList() ;
            // 事务批量提交
            await _roleMenuRepository.RunTransAsync(rep =>
            {
                foreach (var did in delIds)
                {
                    rep.Delete(did);
                }
                foreach (var ad in adMenus)
                {
                    org_role_menu rMenu = new org_role_menu()
                    {
                        sId = Guid.NewGuid().ToString(),
                        dCreateTime = DateTime.Now,
                        slMenuId = ad.sId,
                        slMenuName = ad.sShowName,
                        slMenuType = ad.sMenuType,
                        sOrgId = this.OrgId,
                        sOrgName = this.OrgName,
                        sRoleId = sId,
                        SPermission = ad.SPermission,
                        iDelete = 0
                    };

                    rep.Insert(rMenu);
                }
            });

            return;
        }
    }
}
